/**
 * 
 */
package travibot.connection.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.CookieHandler;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Hashtable;
import travibot.connection.ConnectionFactory;
import travibot.connection.cookies.TraviBotCookieHandler;

/**
 * @author tajzivit
 *
 */
public class HttpConnectionFactory extends ConnectionFactory {

    private URL baseURL = null;
    private Hashtable<String, String> arguments = new Hashtable<String, String>();
    HttpURLConnection connection = null; 
    
    @Override
    public void close() {

        if(connection != null)
            connection.disconnect();
    }

    @Override
    public void connect(String url) {

        if(connection == null)
            return;
        
        try {
            connection.connect();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public InputStream getInputStream(String url) {

        try {
            manageConnection(new URL(baseURL, url));
            
            return connection.getInputStream();
        }
        catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return null;
    }

    @Override
    public String getInputStreamAsString(String url) {

        InputStream inputStream = getInputStream(url);
        StringBuffer result = new StringBuffer();
        
        if(null != inputStream){
            
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            
            BufferedReader reader = new BufferedReader(inputStreamReader);
            
            String line = "";
            
            try {
                while((line = reader.readLine()) != null){
                    result.append(line);
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        return result.toString();
    }

    @Override
    public OutputStream getOutputStream(String url) {

        try {
            manageConnection(new URL(baseURL, url));
            
            return connection.getOutputStream();
        
        }
        catch (MalformedURLException e) {
            e.printStackTrace();
        }
        catch(IOException e){
            e.printStackTrace();
        }
        
        return null;
        
    }

    @Override
    public void open() {

        // TODO Auto-generated method stub
        
    }

    @Override
    public void setBaseURL(String baseURL) {

        try {
            this.baseURL = new URL(getProtocol(), baseURL, "");
        }
        catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void addArgument(String key, String value) {

        arguments.put(key, value);
    }

    @Override
    public void send(String url) {

        if(arguments.size() > 0){
        OutputStreamWriter out = new OutputStreamWriter(getOutputStream(url));
        
        Enumeration<String> keyEnumeration = arguments.keys();
        
        try{
            
            boolean isFirst = true;

            while(keyEnumeration.hasMoreElements()){

                String key = keyEnumeration.nextElement();
                String value = arguments.get(key);

                if(isFirst){
                    out.write(MessageFormat.format("?{0}={1}", new Object[]{key, value}));
                    
                    isFirst = false;
                }
                else
                    out.write(MessageFormat.format("&{0}={1}", new Object[]{key, value}));
            }

            out.flush();
            out.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        
        arguments.clear();
        }
    }

    @Override
    protected void setCookieHandler() {

        CookieHandler.setDefault(new TraviBotCookieHandler());
    }
    
    private void manageConnection(URL url) throws IOException{
        
        if(connection == null || (connection != null && !connection.getURL().equals(url))){
            connection = (HttpURLConnection)url.openConnection();
            
            connection.setDoInput(true);
            connection.setDoOutput(true);
            
            connection.setRequestMethod(getRequestMethod());
        }
    }
}
